﻿import {buildChart as smtBuildChart} from './echart-lineArea-SMT';
import {colorHelper} from '@/utils/colorHelper';

const chart = function (myChart, opt) {
  var config = opt.others.config;
  var labelOption = opt.others.labelOption;
  var datamarkingopt = opt.others.datamarking;
  var datamarkingmapping = {}
  delete opt.others.config;
  delete opt.others.labelOption;
  delete opt.others.data;
  delete opt.others.datamarking;
  //处理数据脱敏
  if (datamarkingopt) {
    datamarkingopt.dimensions.forEach(function (dko) {
      if (dko.DataMarkingEnable) {
        datamarkingmapping[dko.name] = true;
      }
    });
  }
  const self = this;

  let chart_opt = {
    //brush: {
    //    toolbox: ['rect', 'clear'],
    //    throttleType: "debounce",
    //    throttleDelay: 500
    //},
    tooltip: {
      formatter: function (args) {
        var tips = "";
        if (Array.isArray(args)) {
          if (args.length > 10) {
            opt.tooltip.trigger = "item";
            setOption(opt);
            return tips;
          }
          var arg0 = args[0];
          tips += opt.others.dimensionField.name + ":" + arg0.name + "<br/>";
          args.forEach(function (arg, idx) {
            if (!isNaN(Number(arg.value))) {
              if (opt.others.subdimensionField || opt.others.measureField2) {
                tips += arg.marker;
              }
              tips += arg.seriesName + ":";
              if (opt.others.measureField2 && arg.seriesName.includes(opt.others.measureField2.name)) {
                tips += Number(arg.value).toMeasureFormart(opt.others.measureField2.numberFormat);
              } else {
                tips += Number(arg.value).toMeasureFormart(opt.others.measureField.numberFormat);
              }
              if (idx != args.length - 1) {
                tips += "<br/>";
              }
            }
          });

        } else {
          tips += opt.others.dimensionField.name + ":" + args.name + "<br/>";
          if (opt.others.subdimensionField || opt.others.measureField2) {
            tips += args.marker;
          }
          tips += args.seriesName + ":";
          if (opt.others.measureField2 && args.seriesName.includes(opt.others.measureField2.name)) {
            tips += Number(args.value).toMeasureFormart(opt.others.measureField2.numberFormat);
          } else {
            tips += Number(args.value).toMeasureFormart(opt.others.measureField.numberFormat);
          }
        }
        return tips;
      }
    },
    legend: {
      formatter: function (name) {
        var result = name;
        if (datamarkingopt && datamarkingmapping[opt.others.subdimensionField.name]) {
          result = result.marking();
        }
        return result;
      }
    }
  };
  var labelFormatter = function (args) {
    var tips = "";
    if (opt.others.measureField2 && args.seriesName.includes(opt.others.measureField2.name)) {
      tips += Number(args.value).toMeasureFormart(opt.others.measureField2.numberFormat);
    } else {
      tips += Number(args.value).toMeasureFormart(opt.others.measureField.numberFormat);
    }
    return tips;
  }
  var setOption = function (opt) {
    chart_opt = $.extend(true, chart_opt, opt);
    chart_opt.series.forEach(function (d) {
      d.label.normal.formatter = labelFormatter;
    });
    myChart.setOption(chart_opt);
  }
  //响应点击事件
  myChart.on("click", function (args) {
    if (args.componentType === "series") {
      const calldata = [{
        field: chart_opt.others.dimensionField,
        value: [args.name]
      }];
      if (chart_opt.others.subdimensionField) {
        calldata.push({
          field: chart_opt.others.subdimensionField,
          value: [args.seriesName]
        });
      }
      if (self.onselected) {
        self.onselected(calldata);
      }
    }
  });


  if (opt) {
    setOption(opt);
  }
  this.setOption = setOption;
  this.update = function (data) {
    var dimensionField = chart_opt.others.dimensionField;
    var measureField = chart_opt.others.measureField;
    var measureField2 = chart_opt.others.measureField2;
    data = Enumerable.from(data).orderBy(function (d) {
      return d[dimensionField.name];
    }).toArray();
    //提取一级维度
    var categories = Enumerable.from(data).select(function (d) {
      return d[dimensionField.name];
    }).distinct().toArray();
    //按二级维度分组
    var groups = [];
    chart_opt.series = [];
    chart_opt.legend.data = [];
    if (chart_opt.others.subdimensionField) {
      groups = Enumerable.from(data).groupBy(function (d) {
        return d[chart_opt.others.subdimensionField.name];
      }).toArray();
      groups.forEach(function (group) {
        var legend = group.key();

        var source = group.getSource();
        var serie = {
          name: legend,
          type: 'line',
          label: labelOption,
          data: [],
          stack: chart_opt.others.stackType ? '总量' : null
        }
        var serie2;

        chart_opt.series.push(serie);
        if (chart_opt.others.measureField2) {
          serie.name = legend + "_" + measureField.name;
          serie2 = {
            name: legend + "_" + measureField2.name,
            type: 'line',
            label: labelOption,
            data: [],
            stack: chart_opt.others.stackType ? '总量2' : null,
            symbol: "emptyRect"
          }
          if (chart_opt.others.direction === "horizon") {
            serie2.yAxisIndex = 1;
          } else {
            serie2.xAxisIndex = 1;
          }
          chart_opt.series.push(serie2);
        }
        chart_opt.legend.data.push(serie.name);
        if (serie2) {
          chart_opt.legend.data.push(serie2.name);
        }
        if (config.fillArea == 1 || chart_opt.others.stackType) {
          serie.areaStyle = {}
          if (serie2) {
            serie2.areaStyle = {}
          }
        }
        categories.forEach(function (c) {
          var find = source.find(function (d) {
            return d[chart_opt.others.dimensionField.name] === c;
          });
          if (find) {
            serie.data.push(find[chart_opt.others.measureField.name]);
          } else {
            serie.data.push(null);
          }
          if (chart_opt.others.measureField2) {
            if (find) {
              serie2.data.push(find[chart_opt.others.measureField2.name]);
            } else {
              serie2.data.push(null);
            }
          }
        });
      });
    } else {
      var serie = {
        name: chart_opt.others.measureField.name,
        type: "line",
        label: labelOption,
        data: data.map(function (d) {
          return d[chart_opt.others.measureField.name];
        }),
        symbol: "emptyCircle"
      }
      chart_opt.series.push(serie);
      var serie2;
      if (chart_opt.others.measureField2) {
        chart_opt.legend.data.push(chart_opt.others.measureField.name, chart_opt.others.measureField2.name);
        serie2 = {
          name: chart_opt.others.measureField2.name,
          type: "line",
          label: labelOption,
          data: data.map(function (d) {
            return d[chart_opt.others.measureField2.name];
          }),
          symbol: "emptyRect"
        }
        if (chart_opt.others.direction === "horizon") {
          serie2.yAxisIndex = 1;
        } else {
          serie2.xAxisIndex = 1;
        }
        chart_opt.series.push(serie2);
      }
      if (config.fillArea == 1 || chart_opt.others.stackType) {
        serie.areaStyle = {}
        if (serie2) {
          serie2.areaStyle = {}
        }
      }

    }
    var cAxis = chart_opt.xAxis.find(function (d) {
      return d.type == "category";
    });
    if (!cAxis) {
      cAxis = chart_opt.yAxis.find(function (d) {
        return d.type == "category";
      });
    }
    cAxis.data = categories;
    chart_opt.others.categories = categories;
    setOption(chart_opt);
  }
};
export const buildChart = function (myChart, data, columnFields, rowFields, options) {
  if (options.isYoy) {
    return smtBuildChart(myChart, data, columnFields, rowFields, options);
  }
  //一级维度
  let dimensionField = columnFields.find(function (d) {
    return d.slaveType === 0;
  });
  //全部度量
  let measureFields = rowFields.filter(function (d) {
    return d.slaveType === 1;
  });
  let measureField = measureFields[0];

  //呈现方向判定
  let direction = "horizon";//横向
  if (!dimensionField) {
    direction = "vertical";//纵向
    dimensionField = rowFields.find(function (d) {
      return d.slaveType === 0;
    });
    measureFields = columnFields.filter(function (d) {
      return d.slaveType === 1;
    });
    measureField = measureFields[0];
  }
  if (!dimensionField || !measureField || !data.length) {
    return;
  }
  //二号度量
  var measureField2 = measureFields[1];
  //二级维度
  var subDimensionField = options.subDimension?options.subDimension[0]:null;
  var config = options.chartConfig;

  //图表间距
  let padding = [30, 10, 15, 10];
  if (config.chartPadding && config.chartPadding != '') {
    var arrayPadding = config.chartPadding.split(' ');
    if (arrayPadding.length >= 4) {
      padding = arrayPadding.map(function (d) {
        return parseInt(d);
      });
    }
  }
  data = Enumerable.from(data).orderBy(function (d) {
    return d[dimensionField.name];
  }).toArray();
  //提取一级维度
  var categories = Enumerable.from(data).select(function (d) {
    return d[dimensionField.name];
  }).distinct().toArray();
  //按二级维度分组
  var groups = [];
  if (subDimensionField) {
    groups = Enumerable.from(data).groupBy(function (d) {
      return d[subDimensionField.name];
    }).toArray();
  }
  //轴文字样式
  var axis_nameTextStyle = {
    color: config.axisStyle.fontColor,
    fontSize: config.axisStyle.fontSize,
    fontFamily: config.axisStyle.fontFamily
  }
  //数据条标签配置
  var labelOption = {
    normal: {
      show: config.textStyle["display"] !== "none",
      distance: 5,
      align: "left",
      verticalAlign: "middle",
      fontSize: config.textStyle["font-size"],
      fontFamily: config.textStyle["font-family"],
      color: config.textStyle["fill"]
    }
  };
  var option_chart = {
    color: config.MultiColors,
    legend: {
      data: [],
      textStyle: axis_nameTextStyle,
      show: config.showLegend == undefined ? true : config.showLegend,
      type: 'scroll',
      pageIconColor: config.axisStyle.fontColor,
      pageTextStyle: axis_nameTextStyle,
      itemWidth: 14,
      itemHeight: 14
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          color: colorHelper.invert(axis_nameTextStyle.color),
          backgroundColor: axis_nameTextStyle.color
        }
      }
    },
    toolbox: {
      feature: {
        saveAsImage: {}
      }
    },
    calculable: true,
    grid: [{
      top: (config.showLegend == undefined || config.showLegend) ? 20 + padding[0] : padding[0],
      left: padding[3],
      bottom: padding[2],
      right: padding[1],
      containLabel: true
    }],
    series: [],
    others: {
      dimensionField: dimensionField,
      measureField: measureField,
      measureField2: measureField2,
      subdimensionField: subDimensionField,
      categories: categories,
      data: data,
      labelOption: labelOption,
      config: config,
      stackType: options.stackType,
      direction: direction,
      datamarking: options.DataMarking
    }
  }

  config.legendPosition = config.legendPosition || "top";
  if (config.legendPosition == "left") {
    option_chart.legend.x = "left";
  } else if (config.legendPosition == "right") {
    option_chart.legend.x = "right";
  }
  //轴线配置
  var axis_axisLine = {
    lineStyle: {
      color: config.axisStyle.tickColor
    },
    show: config.showAxisLine == undefined ? true : config.showAxisLine
  }
  //定义轴方向
  if (direction === "horizon") {
    labelOption.normal.position = "top";
    option_chart.xAxis = [{
      type: 'category',
      axisTick: {show: false},
      data: categories,
      name: config.xAxisLabelRotate ? "" : dimensionField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        //interval: 0,
        fontWeight: "lighter",
        rotate: config.xAxisLabelRotate != undefined ? config.xAxisLabelRotate : 0,
        show: config.showAxisLabel ? config.showAxisLabel.category : true
      },
      nameLocation: "middle",
      nameGap: config.axisStyle.fontSize * 1.8,
      gridIndex: 0
    }];
    if (config.xAxisName) {
      if (config.xAxisName.show) {
        if (config.xAxisName.name) {
          option_chart.xAxis[0].name = config.xAxisName.name;
        }
      } else {
        option_chart.xAxis[0].name = "";
      }
    }
    option_chart.yAxis = [{
      type: 'value',
      name: measureField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisTick: axis_axisLine,
      splitLine: {
        show: config.showSplitLine,
        lineStyle: {
          color: config.axisStyle.tickColor
        }
      },
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        show: config.showAxisLabel ? config.showAxisLabel.value : true
      },
      gridIndex: 0
    }];
    if (config.yAxisName) {
      if (config.yAxisName.show) {
        if (config.yAxisName.name) {
          option_chart.yAxis[0].name = config.yAxisName.name;
        }
      } else {
        option_chart.yAxis[0].name = "";
      }
    }
    if (config.valueRange) {
      if (!isNaN(Number(config.valueRange.min)) && config.valueRange.min != null && config.valueRange.min.length) {
        option_chart.yAxis[0].min = Number(config.valueRange.min);
      }
      if (!isNaN(Number(config.valueRange.max)) && config.valueRange.max != null && config.valueRange.max.length) {
        option_chart.yAxis[0].max = Number(config.valueRange.max);
      }
    }
    if (measureField2) {
      option_chart.yAxis.push({
        type: 'value',
        name: measureField2.name,
        nameTextStyle: axis_nameTextStyle,
        axisLine: axis_axisLine,
        axisTick: axis_axisLine,
        splitLine: {
          show: config.showSplitLine,
          lineStyle: {
            color: config.axisStyle.tickColor
          }
        },
        axisLabel: {
          color: axis_nameTextStyle.color,
          fontSize: axis_nameTextStyle.fontSize,
          fontFamily: axis_nameTextStyle.fontFamily,
          show: config.showAxisLabel ? config.showAxisLabel.value2 : true
        },
        gridIndex: 0
      });
      if (config.yAxisName2) {
        if (config.yAxisName2.show) {
          if (config.yAxisName2.name) {
            option_chart.yAxis[1].name = config.yAxisName2.name;
          }
        } else {
          option_chart.yAxis[1].name = "";
        }
      }
      if (config.valueRange2) {
        if (!isNaN(Number(config.valueRange2.min)) && config.valueRange2.min != null && config.valueRange2.min.length) {
          option_chart.yAxis[1].min = Number(config.valueRange2.min);
        }
        if (!isNaN(Number(config.valueRange2.max)) && config.valueRange2.max != null && config.valueRange2.max.length) {
          option_chart.yAxis[1].max = Number(config.valueRange2.max);
        }
      }
    }
  } else {
    labelOption.normal.position = "insideRight";
    option_chart.xAxis = [{
      type: 'value',
      name: measureField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisTick: axis_axisLine,
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        show: config.showAxisLabel ? config.showAxisLabel.value : true
      },
      splitLine: {
        show: config.showSplitLine,
        lineStyle: {
          color: config.axisStyle.tickColor
        }
      },
      nameLocation: "middle",
      nameGap: config.axisStyle.fontSize * 1.8,
      gridIndex: 0
    }];
    if (config.yAxisName) {
      if (config.yAxisName.show) {
        if (config.yAxisName.name) {
          option_chart.xAxis[0].name = config.yAxisName.name;
        }
      } else {
        option_chart.xAxis[0].name = "";
      }
    }
    if (config.valueRange) {
      if (!isNaN(Number(config.valueRange.min)) && config.valueRange.min != null && config.valueRange.min.length) {
        option_chart.xAxis[0].min = Number(config.valueRange.min);
      }
      if (!isNaN(Number(config.valueRange.max)) && config.valueRange.max != null && config.valueRange.max.length) {
        option_chart.xAxis[0].max = Number(config.valueRange.max);
      }
    }
    if (measureField2) {
      option_chart.xAxis.push({
        type: 'value',
        name: measureField2.name,
        nameTextStyle: axis_nameTextStyle,
        axisLine: axis_axisLine,
        axisTick: axis_axisLine,
        splitLine: {
          show: config.showSplitLine,
          lineStyle: {
            color: config.axisStyle.tickColor
          }
        },
        axisLabel: {
          color: axis_nameTextStyle.color,
          fontSize: axis_nameTextStyle.fontSize,
          fontFamily: axis_nameTextStyle.fontFamily,
          show: config.showAxisLabel ? config.showAxisLabel.value2 : true
        },
        nameLocation: "middle",
        nameGap: config.axisStyle.fontSize * 1.8,
        gridIndex: 0
      });
      if (config.yAxisName2) {
        if (config.yAxisName2.show) {
          if (config.yAxisName2.name) {
            option_chart.xAxis[1].name = config.yAxisName2.name;
          }
        } else {
          option_chart.xAxis[1].name = "";
        }
      }
      if (config.valueRange2) {
        if (!isNaN(Number(config.valueRange2.min)) && config.valueRange2.min != null && config.valueRange2.min.length) {
          option_chart.xAxis[1].min = Number(config.valueRange2.min);
        }
        if (!isNaN(Number(config.valueRange2.max)) && config.valueRange2.max != null && config.valueRange2.max.length) {
          option_chart.xAxis[1].max = Number(config.valueRange2.max);
        }
      }
    }
    option_chart.yAxis = [{
      type: 'category',
      axisTick: {show: false},
      data: categories,
      name: config.xAxisLabelRotate ? "" : dimensionField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        //interval: 0,
        fontWeight: "lighter",
        rotate: config.xAxisLabelRotate != undefined ? config.xAxisLabelRotate : 0,
        show: config.showAxisLabel ? config.showAxisLabel.category : true
      },
      nameLocation: "start",
      inverse: true,
      gridIndex: 0
    }];
    if (config.xAxisName) {
      if (config.xAxisName.show) {
        if (config.xAxisName.name) {
          option_chart.yAxis[0].name = config.xAxisName.name;
        }
      } else {
        option_chart.yAxis[0].name = "";
      }
    }
  }
  if (subDimensionField) {
    groups.forEach(function (group) {
      var legend = group.key();

      var source = group.getSource();
      var serie = {
        name: legend,
        type: 'line',
        label: labelOption,
        data: [],
        stack: options.stackType ? '总量' : null,
        smooth: config.lineSmooth
      }
      var serie2;

      option_chart.series.push(serie);
      if (measureField2) {
        serie.name = legend + "_" + measureField.name;
        serie2 = {
          name: legend + "_" + measureField2.name,
          type: 'line',
          label: labelOption,
          data: [],
          stack: options.stackType ? '总量2' : null,
          symbol: "emptyRect",
          smooth: config.lineSmooth
        }
        if (direction === "horizon") {
          serie2.yAxisIndex = 1;
        } else {
          serie2.xAxisIndex = 1;
        }
        option_chart.series.push(serie2);
      }
      option_chart.legend.data.push(serie.name);
      if (serie2) {
        option_chart.legend.data.push(serie2.name);
      }
      if (config.fillArea == 1 || options.stackType) {
        serie.areaStyle = {}
        if (serie2) {
          serie2.areaStyle = {}
        }
      }
      categories.forEach(function (c) {
        var find = source.find(function (d) {
          return d[dimensionField.name] === c;
        });
        if (find) {
          serie.data.push(find[measureField.name]);
        } else {
          serie.data.push(null);
        }
        if (measureField2) {
          if (find) {
            serie2.data.push(find[measureField2.name]);
          } else {
            serie2.data.push(null);
          }
        }
      });
    });
  } else {
    var serie = {
      name: measureField.name,
      type: "line",
      label: labelOption,
      data: data.map(function (d) {
        return d[measureField.name];
      }),
      symbol: "emptyCircle",
      smooth: config.lineSmooth
    }
    option_chart.series.push(serie);
    var serie2;
    if (measureField2) {
      option_chart.legend.data.push(measureField.name, measureField2.name);
      serie2 = {
        name: measureField2.name,
        type: "line",
        label: labelOption,
        data: data.map(function (d) {
          return d[measureField2.name];
        }),
        symbol: "emptyRect",
        smooth: config.lineSmooth
      }
      if (direction === "horizon") {
        serie2.yAxisIndex = 1;
      } else {
        serie2.xAxisIndex = 1;
      }
      option_chart.series.push(serie2);
    }
    if (config.fillArea == 1 || options.stackType) {
      serie.areaStyle = {}
      if (serie2) {
        serie2.areaStyle = {}
      }
    }

  }

  const chartInstance = new chart(myChart, option_chart);
  return chartInstance;
};
